import React, { Suspense } from 'react';
import {
  Route,
  Redirect,
  BrowserRouter,
  Switch,
  Link,
  useLocation,
  RouteComponentProps,
  withRouter
} from 'react-router-dom';
import { RootState } from '@/store';
import { updateToken } from '@/store/user';
import { setMenus } from '@/store/global';
import { useSelector, useDispatch } from 'react-redux';
import { decodeQuery, encodeQuery } from '../utils';
import { Spin } from 'antd';
import { root } from './router.config';
import Layouts from '@/layouts';
import type { IRouter } from './router.d';
import type { IAuthMenusRes } from '@/api/index.d';

/**
 * 递归router
*/
interface IRenderProp {
  routes: IRouter[];
}

const RenderContent: React.FC<IRenderProp> = ({ routes }) => {
  return (
    <Switch>
      <Suspense fallback={<Spin tip="加载中..." delay={300} className="page-spin-container" />}>
        {
          routes.map((route: IRouter) =>
            typeof route.component !== 'string'
              ? route.children && route.children.length
                ? <RenderContent routes={route.children} key={route.path} />
                : <Route path={route.path} component={route.component} key={route.path} />

              : <Route path={route.path} render={(prop: RouteComponentProps) => <Layouts {...prop}>
                <Suspense fallback={<Spin tip="加载中..." delay={300} className="page-spin-container" />}>
                  {
                    route.children && route.children.length ? <RenderContent routes={route.children} /> : null
                  }
                </Suspense>
              </Layouts>} key={route.path} />
          )
        }
      </Suspense>
    </Switch>
  )
}

const Routes = withRouter(() => {
  const routes = useSelector<RootState, IRouter[]>(state => state.global.routers);
  return <RenderContent routes={routes} />
})

/**
 * 权鉴
*/
const Authverify: React.FC = () => {
  const dispatch = useDispatch();
  const location = useLocation();
  const token = useSelector<RootState, string>(state => state.user.token);
  const menuKeys = useSelector<RootState, IAuthMenusRes[]>(state => state.global.menuKeys)
  const { pathname } = location;

  // url  query参数
  let query = decodeQuery(location.search);
  const { accessToken } = query

  // 如果url带有accessToken信息 更新本地信息 token 信息
  if (accessToken) {
    dispatch(updateToken(accessToken));
    delete query.accessToken;
    return <Redirect to={{ pathname, search: encodeQuery(query) }} />
  }

  // 如果本地不存在token信息直接跳转到登录页
  if (!token) return <Redirect to="/login" />;

  // 如果本地的menuKeys 没有请求过 则返回loading
  if (!menuKeys.length) {
    dispatch(setMenus())
    return <div className="ant-spin-nested-loading global-spin-container">
      <Spin tip="加载中..." delay={0} />
      <div className="ant-spin-container ant-spin-blur"></div>
    </div>
  }

  // 如果路由名称是空 则跳转home页面
  if (!pathname || pathname === '/' || (token && pathname === '/login')) {
    return <Redirect to={root} />
  }

  return <Link to={location} />
}

const Router: React.FC = () => {
  return (
    <BrowserRouter>
      <Authverify />
      <Routes />
    </BrowserRouter>
  )
}

export default Router
